/**
 * 
 */
package vue.popup;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import model.preprocessor.EPreProcessor;
import model.solver.ESolver;
import model.solver.ImportESolver;
import vue.session.IGCNFUse;
import controller.ISessionManager;

/**
 * A pop up menu for {@link IGCNFUse}.
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class JPopupCNFUse extends JPopupMenu implements IJPopupMenu, ActionListener {


	private static final long				serialVersionUID	= 1L;

	public static final String				ITEM_PREPROC		= "Execute preprocessor";
	public static final String				ITEM_SOLVER			= "Execute solver";
	public static final String				ITEM_CHECK_STAT		= "Check stat";
	public static final String				ITEM_EXPORT			= "Export";

	protected JMenu							executeSolverItem;
	protected JMenu							executePreprocItem;
	protected Map<JMenuItem, ESolver>		solverItem			= new HashMap<JMenuItem, ESolver>();
	protected Map<JMenuItem, ImportESolver>	importSolverItem	= new HashMap<JMenuItem, ImportESolver>();

	protected Map<JMenuItem, EPreProcessor>	preprocItem			= new HashMap<JMenuItem, EPreProcessor>();

	protected JMenuItem						checkStatItem;
	protected JMenuItem						exportItem;


	private ISessionManager					manager;
	private IGCNFUse						cnfuse;

	/**
	 * Create the pop {@link JPopupCNFUse}.
	 * 
	 * @param cnfuse
	 *            the {@link IGCNFUse} associate
	 * @param manager
	 *            the session manager
	 */
	public JPopupCNFUse(IGCNFUse cnfuse, ISessionManager manager) {
		this.cnfuse = cnfuse;
		this.manager = manager;

		createMenu();
	}


	/**
	 * Create the pop up menu for the CNF.
	 */
	protected void createMenu() {
		// preproc
		executePreprocItem = new JMenu(ITEM_PREPROC);
		for (EPreProcessor p : manager.getAvailablePreProcessor())
		{
			if (p == EPreProcessor.UNKNOW)
				continue;

			JMenuItem item = new JMenuItem(p.getDescription());
			item.addActionListener(this);
			preprocItem.put(item, p);
			executePreprocItem.add(item);
		}
		// executePreprocItem.addActionListener(this);
		add(executePreprocItem);

		// solver
		executeSolverItem = new JMenu(ITEM_SOLVER);
		for (ESolver s : manager.getAvailableSolver())
		{
			if (s == ESolver.UNKNOW)
				continue;

			JMenuItem item = new JMenuItem(s.getDescription());
			item.addActionListener(this);
			solverItem.put(item, s);
			executeSolverItem.add(item);
		}
		for (ImportESolver s : manager.getAvailableImportSolver())
		{
			JMenuItem item = new JMenuItem(s.getDescription());
			item.addActionListener(this);
			importSolverItem.put(item, s);
			executeSolverItem.add(item);
		}

		// executeSolverItem.addActionListener(this);
		add(executeSolverItem);

		addSeparator();

		// export
		exportItem = new JMenuItem(ITEM_EXPORT);
		exportItem.addActionListener(this);

		add(exportItem);

		// stat
		checkStatItem = new JMenuItem(ITEM_CHECK_STAT);
		checkStatItem.addActionListener(this);

		add(checkStatItem);

		addSeparator();
	}


	@Override
	public void refresh() {
		// refresh le menu des solvers
		executeSolverItem.removeAll();
		for (ESolver s : manager.getAvailableSolver())
		{
			if (s == ESolver.UNKNOW)
				continue;

			JMenuItem item = new JMenuItem(s.getDescription());
			item.addActionListener(this);
			solverItem.put(item, s);
			executeSolverItem.add(item);
		}
		for (ImportESolver s : manager.getAvailableImportSolver())
		{
			JMenuItem item = new JMenuItem(s.getDescription());
			item.addActionListener(this);
			importSolverItem.put(item, s);
			executeSolverItem.add(item);
		}
	}

	/**
	 * Open a dialog to execute a solver on the cnf.
	 * 
	 * @param solver
	 *            the default choice if it is an {@link ESolver}
	 * @param firstImport
	 *            the default choice if it is an {@link ImportESolver}
	 */
	public void executeSolverMenu(ESolver solver, ImportESolver firstImport) {
		IGSolverDialog dialog = new IGSolverDialog(manager, cnfuse.getCnfuse(), null, solver, firstImport);
		dialog.setVisible(true);
	}


	/**
	 * Open a dialog to execute a preprocessor on the cnf.
	 * 
	 * @param preproc
	 *            the default choice
	 */
	public void executePreprocMenu(EPreProcessor preproc) {
		IGPreprocessorDialog dialog = new IGPreprocessorDialog(manager, cnfuse.getCnfuse(), null, preproc);
		dialog.setVisible(true);
	}

	/**
	 * Open a dialog to export the cnf.
	 */
	public void export() {
		IGExportCNFDialog dialog = new IGExportCNFDialog(manager, cnfuse.getCnfuse(), null);
		dialog.setVisible(true);
	}

	/**
	 * Ask to check the stat of the cnf.
	 */
	public void checkStat() {
		manager.checkCNFStat(cnfuse.getCnfuse());
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		for (JMenuItem pItem : preprocItem.keySet())
			if (e.getSource() == pItem)
			{// execute preproc
				executePreprocMenu(preprocItem.get(pItem));
				return;
			}
		for (JMenuItem pItem : solverItem.keySet())
			if (e.getSource() == pItem)
			{// execute solver
				executeSolverMenu(solverItem.get(pItem), null);
				return;
			}
		for (JMenuItem pItem : importSolverItem.keySet())
			if (e.getSource() == pItem)
			{// execute imported solver
				executeSolverMenu(null, importSolverItem.get(pItem));
				return;
			}
		if (e.getSource() == checkStatItem)
		{// check stat
			checkStat();
			return;
		}
		if (e.getSource() == exportItem)
		{// export
			export();
			return;
		}

	}

}
